package cn.op.portal.common.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.jdbc.core.simple.ParameterizedSingleColumnRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;

import cn.op.portal.common.dao.BaseDao;
import cn.op.portal.common.vo.Page;

/**
 * 包含了基本基本增删改查方法的Dao实现类，其他具体Dao可继承此类
 * @author lufei
 * @param <T>
 */
public class BaseDaoImpl<T> implements BaseDao<T> {
	
	@Resource(name="jdbcTemplate")
	protected SimpleJdbcTemplate jdbcTemplate;
	
	private Class<T> clazz;

	public BaseDaoImpl() {
		ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
		clazz = (Class) pt.getActualTypeArguments()[0];

		System.out.println("clazz = " + clazz);
	}

	@Override
	public void add(String sql, Object... values) {
		jdbcTemplate.update(sql, values);
	}

	@Override
	public void delete(String sql, Object... values) {
		jdbcTemplate.update(sql, values);
	}

	@Override
	public void update(String sql, Object... values) {
		System.out.println(sql);
		jdbcTemplate.update(sql, values);
	}

	@Override
	public T findById(String sql, Object... values) {	
		T object = null;
		try {
			object = jdbcTemplate.queryForObject(sql, ParameterizedBeanPropertyRowMapper.newInstance(clazz), values);
		} catch (DataAccessException e) {
			e.printStackTrace();
		}		
		return object;
	}
	
	@Override
	public Page<T> findPage(String sql, int pageNum, int pageSize, Object... values) throws Exception {
		int count = getCount(sql, values);
		Page<T> page = new Page<T>(count, pageNum, pageSize);
		List<T> list = findObjectList(sql, pageNum, pageSize, values);
		page.setList(list);
		
		return page;
	}

	@Override
	public <R> Page<R> findPage(String sql, int pageNum, int pageSize, Class R, Object... values) throws Exception {
		int count = getCount(sql, values);
		Page<R> page = new Page<R>(count, pageNum, pageSize);
		List<R> list = findObjectList(sql, pageNum, pageSize, R, values);
		page.setList(list);
		
		return page;
	}


	@Override
	public List<T> findObjectList(String sql, int pageNum, int pageSize, Object... values) {
		StringBuilder sb = new StringBuilder();
		sb.append(sql);
		int frist = (pageNum - 1) * pageSize;
		sb.append(" limit ").append(frist).append(",").append(pageSize);

		System.out.println("-----------77-------------"+sb.toString());
		List<T> list = this.jdbcTemplate.query(sb.toString(),ParameterizedBeanPropertyRowMapper.newInstance(clazz),values);

		return list;
	}

	@Override
	public <R extends Object> List<R> findObjectList(String sql, int pageNum, int pageSize, Class R, Object... values) {
		StringBuilder sb = new StringBuilder();
		sb.append(sql);
		int frist = (pageNum - 1) * pageSize;

		sb.append(" limit ").append(frist).append(",").append(pageSize);
		System.out.println("-----------77-------------"+sb.toString());
		List<R> list = this.jdbcTemplate.query(sb.toString(),ParameterizedBeanPropertyRowMapper.newInstance(R),values);
		
		return list;
	}
	
	
	public int getCount(final String sql, final Object... values) throws Exception{
		String countSql = prepareCountSql(sql);

		try {
			int count = this.jdbcTemplate.getJdbcOperations().queryForInt(countSql, values);
			return count;
		} catch (Exception e) {
			throw new RuntimeException("sql can't be auto count,sql is:" + countSql, e);
		}
	}
	

	private String prepareCountSql(String orgSql) {
		String fromSql = orgSql;
		//select子句的order by子句会影响count查询,进行�?单的排除.
		fromSql = "from " + StringUtils.substringAfter(fromSql, "from");
		fromSql = StringUtils.substringBefore(fromSql, "order by");

		String countHql = "select count(*) " + fromSql;
		return countHql;
	}
	
	public SimpleJdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(SimpleJdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

}
